/**
 * 移动端响应式工具类
 * 提供 viewport 单位计算和响应式断点判断
 */

// 设计稿基准宽度
export const DESIGN_WIDTH = 375;
export const DESIGN_HEIGHT = 667;

// 断点配置
export const BREAKPOINTS = {
  xs: 375,
  sm: 640,
  md: 768,
  lg: 1024,
  xl: 1280,
  '2xl': 1536,
} as const;

// 设备类型
export type DeviceType = 'mobile' | 'tablet' | 'desktop';

/**
 * 将 px 转换为 vw
 * @param px 像素值
 * @param designWidth 设计稿宽度，默认 375
 * @returns vw 值
 */
export function pxToVw(px: number, designWidth: number = DESIGN_WIDTH): string {
  return `${(px / designWidth) * 100}vw`;
}

/**
 * 将 px 转换为 vh
 * @param px 像素值
 * @param designHeight 设计稿高度，默认 667
 * @returns vh 值
 */
export function pxToVh(px: number, designHeight: number = DESIGN_HEIGHT): string {
  return `${(px / designHeight) * 100}vh`;
}

/**
 * 获取当前设备类型
 * @returns 设备类型
 */
export function getDeviceType(): DeviceType {
  if (typeof window === 'undefined') return 'desktop';
  
  const width = window.innerWidth;
  
  if (width < BREAKPOINTS.md) {
    return 'mobile';
  } else if (width < BREAKPOINTS.lg) {
    return 'tablet';
  } else {
    return 'desktop';
  }
}

/**
 * 判断是否为移动设备
 * @returns 是否为移动设备
 */
export function isMobile(): boolean {
  return getDeviceType() === 'mobile';
}

/**
 * 判断是否为平板设备
 * @returns 是否为平板设备
 */
export function isTablet(): boolean {
  return getDeviceType() === 'tablet';
}

/**
 * 判断是否为桌面设备
 * @returns 是否为桌面设备
 */
export function isDesktop(): boolean {
  return getDeviceType() === 'desktop';
}

/**
 * 获取当前视口宽度
 * @returns 视口宽度
 */
export function getViewportWidth(): number {
  if (typeof window === 'undefined') return 1920;
  return window.innerWidth;
}

/**
 * 获取当前视口高度
 * @returns 视口高度
 */
export function getViewportHeight(): number {
  if (typeof window === 'undefined') return 1080;
  return window.innerHeight;
}

/**
 * 响应式值映射
 * @param values 不同断点对应的值
 * @returns 当前断点对应的值
 */
export function responsiveValue<T>(values: {
  mobile?: T;
  tablet?: T;
  desktop?: T;
  default?: T;
}): T | undefined {
  const deviceType = getDeviceType();
  
  switch (deviceType) {
    case 'mobile':
      return values.mobile ?? values.default;
    case 'tablet':
      return values.tablet ?? values.mobile ?? values.default;
    case 'desktop':
      return values.desktop ?? values.tablet ?? values.mobile ?? values.default;
    default:
      return values.default;
  }
}

/**
 * 响应式样式对象生成器
 * @param styles 不同断点对应的样式
 * @returns 当前断点对应的样式对象
 */
export function responsiveStyles(styles: {
  mobile?: Record<string, string | number>;
  tablet?: Record<string, string | number>;
  desktop?: Record<string, string | number>;
  default?: Record<string, string | number>;
}): Record<string, string | number> {
  const deviceType = getDeviceType();
  
  switch (deviceType) {
    case 'mobile':
      return { ...styles.default, ...styles.mobile };
    case 'tablet':
      return { ...styles.default, ...styles.mobile, ...styles.tablet };
    case 'desktop':
      return { ...styles.default, ...styles.mobile, ...styles.tablet, ...styles.desktop };
    default:
      return styles.default || {};
  }
}

/**
 * 安全区域适配
 * 用于处理刘海屏、底部操作条等安全区域
 */
export const safeArea = {
  top: 'env(safe-area-inset-top)',
  right: 'env(safe-area-inset-right)',
  bottom: 'env(safe-area-inset-bottom)',
  left: 'env(safe-area-inset-left)',
};

/**
 * 获取安全区域样式
 * @param sides 需要应用安全区域的边
 * @returns 安全区域样式对象
 */
export function getSafeAreaStyles(sides: ('top' | 'right' | 'bottom' | 'left')[] = ['top', 'bottom']) {
  const styles: Record<string, string> = {};
  
  sides.forEach(side => {
    styles[`padding-${side}`] = safeArea[side];
  });
  
  return styles;
}

/**
 * 防抖函数
 * @param func 要防抖的函数
 * @param wait 等待时间
 * @returns 防抖后的函数
 */
export function debounce<T extends (...args: any[]) => any>(
  func: T,
  wait: number
): (...args: Parameters<T>) => void {
  let timeout: NodeJS.Timeout;
  
  return (...args: Parameters<T>) => {
    clearTimeout(timeout);
    timeout = setTimeout(() => func(...args), wait);
  };
}

/**
 * 节流函数
 * @param func 要节流的函数
 * @param limit 限制时间
 * @returns 节流后的函数
 */
export function throttle<T extends (...args: any[]) => any>(
  func: T,
  limit: number
): (...args: Parameters<T>) => void {
  let inThrottle: boolean;
  
  return (...args: Parameters<T>) => {
    if (!inThrottle) {
      func(...args);
      inThrottle = true;
      setTimeout(() => (inThrottle = false), limit);
    }
  };
}

// 监听窗口大小变化
export const onResize = (callback: () => void) => {
  if (typeof window === 'undefined') return;
  
  const debouncedCallback = debounce(callback, 100);
  window.addEventListener('resize', debouncedCallback);
  
  return () => {
    window.removeEventListener('resize', debouncedCallback);
  };
}; 